home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / system_tools.e < prev    next >
Text File  |  2000-03-25  |  55KB  |  1,650 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class SYSTEM_TOOLS
  17.    --
  18.    -- Singleton object to handle system dependant information.
  19.    -- This singleton is shared via the GLOBALS.`system_tools' once function.
  20.    --
  21.    -- Only this object is supposed to handle contents of the `SmallEiffel'
  22.    -- system environment variable.
  23.    --
  24.    -- You may also want to customize this class in order to support a
  25.    -- new operating system (please let us know).
  26.    --
  27.  
  28. inherit GLOBALS;
  29.  
  30. creation make, install
  31.  
  32. feature {NONE}
  33.  
  34.    -- Currently handled system list :
  35.    amiga_system:       STRING is "Amiga";
  36.    beos_system:        STRING is "BeOS";
  37.    dos_system:         STRING is "DOS";
  38.    macintosh_system:   STRING is "Macintosh";
  39.    os2_system:         STRING is "OS2";
  40.    unix_system:        STRING is "UNIX";
  41.    vms_system:         STRING is "VMS";
  42.    windows_system:     STRING is "Windows";
  43.  
  44.    -- Currently handled C compiler list :
  45.    gcc:                STRING is "gcc";
  46.    lcc_win32:          STRING is "lcc-win32";
  47.    cc:                 STRING is "cc";
  48.    wcl386:             STRING is "wcl386";
  49.    bcc32:              STRING is "bcc32";
  50.    bcc32i:             STRING is "bcc32i"; -- Is this one used ?
  51.    cl:                 STRING is "cl";
  52.    sas_c:              STRING is "sc";
  53.    dice:               STRING is "dice";
  54.    vbcc:               STRING is "vbcc";
  55.    ccc:                STRING is "ccc";
  56.  
  57. feature {INSTALL}
  58.  
  59.    system_list: ARRAY[STRING] is
  60.       once
  61.          Result := << amiga_system,
  62.                       beos_system,
  63.                       dos_system,
  64.                       macintosh_system,
  65.                       os2_system,
  66.                       unix_system,
  67.                       vms_system,
  68.                       windows_system
  69.                       >>;
  70.       end;
  71.  
  72.    compiler_list: ARRAY[STRING] is
  73.       once
  74.      Result := <<gcc, lcc_win32, cc, wcl386, bcc32, bcc32i,
  75.              cl, sas_c, dice, vbcc, ccc>>;
  76.       end;
  77.  
  78.    add_x_suffix(cmd: STRING) is
  79.       local
  80.          suffix: STRING;
  81.       do
  82.          suffix := x_suffix;
  83.          if not cmd.has_suffix(suffix) then
  84.             cmd.append(suffix);
  85.          end;
  86.       end;
  87.  
  88.    make is
  89.       local
  90.          system_se_path: STRING;
  91.          i: INTEGER;
  92.       do
  93.          system_se_path := get_environment_variable(fz_se);
  94.          if system_se_path = Void then
  95.             system_se_path := fz_se.twin;
  96.             system_se_path.to_upper;
  97.             system_se_path := get_environment_variable(system_se_path);
  98.             if system_se_path = Void then
  99.                echo.put_string(
  100.                   "System environment variable %"SmallEiffel%" not set.%N%
  101.                   %Trying default value: %"");
  102.                system_se_path := "/usr/lib/SmallEiffel/sys/system.se";
  103.                echo.put_string(system_se_path);
  104.                echo.put_string(fz_03);
  105.             end;
  106.          else
  107.             echo.put_string("SmallEiffel=%"");
  108.             echo.put_string(system_se_path);
  109.             echo.put_string(fz_b0);
  110.          end;
  111.          if system_se_path.has_suffix(fz_system_se) then
  112.             echo.sfr_connect(tmp_file_read,system_se_path);
  113.          else
  114.             echo.put_string(
  115.                "You should update the value of the %"SmallEiffel%" %
  116.                %system environment variable.%N%
  117.                %Since release -0.79, the %"SmallEiffel%" system %
  118.                %environment variable must be the absolute path of %
  119.                %the %"system.se%" file.%N%
  120.                %For example %"/usr/lib/SmallEiffel/sys/system.se%" %
  121.                %under Unix like system.%N");
  122.             if system_se_path.has('/') then
  123.                echo.put_string("Hope this is a Unix like system.%N");
  124.                tmp_path.copy(system_se_path);
  125.                tmp_path.extend_unless('/');
  126.                tmp_path.append(fz_sys);
  127.                tmp_path.extend('/');
  128.                tmp_path.append(fz_system_se);
  129.                echo.sfr_connect(tmp_file_read,tmp_path);
  130.             end;
  131.             if not tmp_file_read.is_connected then
  132.                if system_se_path.has('\') then
  133.                   echo.put_string("Hope this is a Windows like system.%N");
  134.                   tmp_path.copy(system_se_path);
  135.                   tmp_path.extend_unless('\');
  136.                   tmp_path.append(fz_sys);
  137.                   tmp_path.extend('\');
  138.                   tmp_path.append(fz_system_se);
  139.                   echo.sfr_connect(tmp_file_read,tmp_path);
  140.                end;
  141.             end;
  142.             if not tmp_file_read.is_connected then
  143.                if system_se_path.has(':') then
  144.                   echo.put_string("Hope this is a Macintosh like system.%N");
  145.                   tmp_path.copy(system_se_path);
  146.                   tmp_path.extend_unless(':');
  147.                   tmp_path.append(fz_sys);
  148.                   tmp_path.extend(':');
  149.                   tmp_path.append(fz_system_se);
  150.                   echo.sfr_connect(tmp_file_read,tmp_path);
  151.                end;
  152.             end;
  153.             if not tmp_file_read.is_connected then
  154.                if system_se_path.has(']') then
  155.                   echo.put_string("Hope this is a VMS system.%N");
  156.                   tmp_path.copy(system_se_path);
  157.                   tmp_path.extend_unless(']');
  158.                   tmp_path.remove_last(1);
  159.                   tmp_path.extend('.');
  160.                   tmp_path.append(fz_sys);
  161.                   tmp_path.extend(']');
  162.                   tmp_path.append(fz_system_se);
  163.                   echo.sfr_connect(tmp_file_read,tmp_path);
  164.                end;
  165.             end;
  166.             if not tmp_file_read.is_connected then
  167.                echo.put_string("Last chance.%N");
  168.                tmp_path.copy(system_se_path);
  169.                tmp_path.append(fz_system_se);
  170.                echo.sfr_connect(tmp_file_read,tmp_path);
  171.             end;
  172.          end;
  173.          if not tmp_file_read.is_connected then
  174.             echo.w_put_string(
  175.                "Unable to find file %"system.se%".%N%
  176.                %Please, set the environment variable %"SmallEiffel%" %
  177.                %with the appropriate absolute path to this file.%N%
  178.                %Example for Unix: %"/usr/lib/SmallEiffel/sys/system.se%"%N%
  179.                %Example for DOS/Windows: %"C:\SmallEiffel\sys\system.se%"%N");
  180.             die_with_code(exit_failure_code);
  181.          end;
  182.          tmp_file_read.read_line;
  183.          system_name := tmp_file_read.last_string;
  184.          i := system_list.index_of(system_name);
  185.          if i > system_list.upper then
  186.             echo.w_put_string("Unknown system name in file%N%"");
  187.             echo.w_put_string(tmp_file_read.path);
  188.             echo.w_put_string("%".%NCurrently handled system names :%N");
  189.             from
  190.                i := 1;
  191.             until
  192.                i > system_list.upper
  193.             loop
  194.                echo.w_put_string(system_list.item(i));
  195.                echo.w_put_character('%N');
  196.                i := i + 1;
  197.             end;
  198.             die_with_code(exit_failure_code);
  199.          else
  200.             system_name := system_list.item(i);
  201.             echo.put_string("System is %"");
  202.             echo.put_string(system_name);
  203.             echo.put_string(fz_b0);
  204.          end;
  205.          sys_directory := tmp_file_read.path.twin;
  206.          sys_directory.remove_suffix(fz_system_se);
  207.          tmp_file_read.disconnect;
  208.          bin_directory := sys_directory.twin;
  209.          parent_directory(bin_directory);
  210.          add_directory(bin_directory,fz_bin);
  211.       end;
  212.  
  213.    system_name: STRING;
  214.  
  215.    install_extra_options is
  216.          -- Add some extra options during `install' time.
  217.       do
  218.          check
  219.             c_compiler /= Void
  220.         -- This ought to be in a require clause, but
  221.         -- `c_compiler' has access restrictions
  222.      end
  223.          if c_compiler = gcc then
  224.             if not c_compiler_options.has('O') then
  225.                append_token(c_compiler_options,"-O2");
  226.             end;
  227.          elseif c_compiler = lcc_win32 then
  228.             if not c_compiler_options.has('O') then
  229.                append_token(c_compiler_options,"-O");
  230.             end;
  231.      elseif c_compiler = sas_c then
  232.         if not Scoptions_exists then
  233.            append_token(c_compiler_options,"Optimize OptimizerTime");
  234.         end;
  235.      elseif c_compiler = dice then
  236.      elseif c_compiler = vbcc then
  237.      elseif c_compiler = ccc then
  238.         if not c_compiler_options.has('O') then
  239.            append_token(c_compiler_options,"-O2");
  240.         end;
  241.          end;
  242.       end;
  243.  
  244. feature {NONE}
  245.  
  246.    sys_directory: STRING;
  247.          -- The SmallEiffel/sys directory computed with the value of
  248.          -- the environment variable `SmallEiffel'.
  249.          -- For example, under UNIX: "/usr/lib/SmallEiffel/sys/"
  250.  
  251.    bin_directory: STRING;
  252.          -- For example, under UNIX: "/usr/lib/SmallEiffel/bin/"
  253.  
  254.    install is
  255.       do
  256.       end;
  257.  
  258. feature {COMPILE}
  259.  
  260.    command_path_in(command, command_name: STRING) is
  261.          -- Append in `command' the correct path for `command_name'.
  262.       do
  263.          if windows_system /= system_name then
  264.             command.append(bin_directory);
  265.          end;
  266.          command.append(command_name);
  267.          command.append(x_suffix);
  268.       end;
  269.  
  270.    cygnus_bug(make_file: STD_FILE_READ; make_script_name: STRING) is
  271.          -- Because of a bug in cygnus on windows 95/NT.
  272.       local
  273.          time_out: INTEGER;
  274.       do
  275.          make_file.connect_to(make_script_name);
  276.          if c_compiler = gcc then
  277.             if system_name = windows_system then
  278.                time_out := 2000;
  279.             elseif system_name = dos_system then
  280.                time_out := 2000;
  281.             end;
  282.          end;
  283.          from
  284.             time_out := 2000;
  285.          until
  286.             time_out = 0 or else make_file.is_connected
  287.          loop
  288.             make_file.connect_to(make_script_name);
  289.             time_out := time_out - 1;
  290.          end;
  291.  
  292.       end;
  293.  
  294. feature {COMPILE,CLEAN}
  295.  
  296.    remove_make_script: STRING is
  297.          -- Compute the corresponding make file script name and remove
  298.          -- the old one if any.
  299.       do
  300.          Result := path_h;
  301.          Result.remove_suffix(h_suffix);
  302.          if c_compiler = sas_c then
  303.             Result.append(lnk_suffix);
  304.             echo.file_removing(Result);
  305.             Result.remove_suffix(lnk_suffix);
  306.          end;
  307.          Result.append(make_suffix);
  308.          echo.file_removing(Result);
  309.       end;
  310.  
  311. feature {SMALL_EIFFEL}
  312.  
  313.    read_loading_path_in(lp: ARRAY[STRING]) is
  314.       do
  315.          loading_path_add(lp,fz_loadpath_se,1);
  316.          tmp_path.copy(sys_directory);
  317.          tmp_path.append("loadpath.");
  318.          tmp_path.append(system_name);
  319.          loading_path_add(lp,tmp_path,1);
  320.       end;
  321.  
  322.    append_lp_in(str: STRING; lp: ARRAY[STRING]) is
  323.       local
  324.          i: INTEGER;
  325.          sed: STRING;
  326.       do
  327.          str.append("%NLoading path is:%N[%N");
  328.          from
  329.             i := lp.lower;
  330.          until
  331.             i > lp.upper
  332.          loop
  333.             str.extend(' ');
  334.             str.extend('%"');
  335.             str.append(lp.item(i));
  336.             str.extend('%"');
  337.             str.extend('%N');
  338.             i := i + 1;
  339.          end;
  340.          str.append("]%NEnvironment Variable %"SmallEiffel%" is:%N");
  341.          sed := get_environment_variable(fz_se);
  342.          if sed = Void then
  343.             str.append("not set.%N");
  344.          else
  345.             str.append(" %"");
  346.             str.append(sed);
  347.             str.append("%".%N");
  348.          end;
  349.       end;
  350.  
  351. feature {GC_HANDLER}
  352.  
  353.    put_mark_stack_and_registers is
  354.          -- Add customized assembly code to mark registers.
  355.       local
  356.          architecture: STRING;
  357.       do
  358.          tmp_path.copy(sys_directory);
  359.          tmp_path.append(fz_gc);
  360.          echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  361.          architecture := echo.read_word_in(tmp_file_read);
  362.          tmp_file_read.disconnect;
  363.          if as_none.is_equal(architecture) then
  364.             eh.append(
  365.                "Assembly Code for Garbage Collector not selected in %"");
  366.             eh.append(tmp_path);
  367.             eh.append(
  368.                "%". Default generic (hazardous) C code is provided.");
  369.             eh.print_as_warning;
  370.             architecture := "generic.c";
  371.          end;
  372.          tmp_path.copy(sys_directory);
  373.          add_directory(tmp_path,fz_gc_lib);
  374.          tmp_path.append(architecture);
  375.          echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  376.          cpp.put_c_file(tmp_file_read);
  377.       end;
  378.  
  379. feature {SHORT_PRINT}
  380.  
  381.    format_directory(format: STRING): STRING is
  382.       require
  383.          format /= Void
  384.       do
  385.          !!Result.make(sys_directory.count + 10);
  386.          Result.copy(sys_directory);
  387.          parent_directory(Result);
  388.          add_directory(Result,"short");
  389.          add_directory(Result,format);
  390.       end;
  391.  
  392. feature
  393.  
  394.    bad_use_exit(command_name: STRING) is
  395.       require
  396.          command_name /= Void
  397.       do
  398.          echo.w_put_string("Bad use of command `");
  399.          echo.w_put_string(command_name);
  400.          echo.w_put_string("'.%N");
  401.          tmp_path.copy(sys_directory);
  402.          parent_directory(tmp_path);
  403.          add_directory(tmp_path,"man");
  404.          tmp_path.append(command_name);
  405.          tmp_path.append(help_suffix);
  406.          echo.w_put_string("See documentation in file:%N   ");
  407.          echo.w_put_string(tmp_path);
  408.          echo.w_put_character('%N');
  409.          die_with_code(exit_failure_code);
  410.       end;
  411.  
  412.    is_c_plus_plus_file_path(path: STRING): BOOLEAN is
  413.      -- True when there `path' has one of the following 
  414.      -- suffix: ".cpp", ".cc", or ".C".
  415.       do
  416.      if path.has_suffix(c_plus_plus_suffix) then
  417.         Result := true;
  418.      elseif path.has_suffix(".cc") then
  419.         Result := true;
  420.      elseif path.has_suffix(".C") then
  421.         Result := true;
  422.      end;
  423.       end;
  424.  
  425. feature {JVM}
  426.  
  427.    class_file_path(path, directory, class_file_name: STRING) is
  428.          -- Prepare `path' using `directory' and `class_file_name'.
  429.       do
  430.          path.clear;
  431.          if vms_system = system_name then
  432.             if directory.first /= '[' then
  433.                path.extend('[');
  434.             end;
  435.          end;
  436.          path.append(directory);
  437.          if slash_separator then
  438.             path.extend_unless('/');
  439.          elseif backslash_separator then
  440.             path.extend_unless('\');
  441.          elseif macintosh_system = system_name then
  442.             path.extend_unless(':');
  443.          elseif amiga_system = system_name then
  444.             path.extend_unless('/');
  445.          elseif vms_system = system_name then
  446.             path.extend_unless(']');
  447.          end;
  448.          path.append(class_file_name);
  449.          path.append(class_suffix);
  450.       end;
  451.  
  452. feature
  453.  
  454.    make_suffix: STRING is
  455.       -- Suffix for make file produced by `compile_to_c'.
  456.       once
  457.          if dos_system = system_name then
  458.             Result := ".BAT";
  459.          elseif windows_system = system_name then
  460.             Result := ".bat";
  461.          elseif vms_system = system_name then
  462.             Result := ".COM";
  463.          elseif os2_system = system_name then
  464.             Result := ".CMD";
  465.          else
  466.             Result := ".make";
  467.          end;
  468.       end;
  469.  
  470.    x_suffix: STRING is
  471.          -- Executable files suffix.
  472.       once
  473.          if dos_system = system_name then
  474.             Result := exe_suffix;
  475.             Result.to_upper;
  476.          elseif vms_system = system_name then
  477.             Result := exe_suffix;
  478.             Result.to_upper;
  479.          elseif os2_system = system_name then
  480.             Result := exe_suffix;
  481.          elseif windows_system = system_name then
  482.             Result := exe_suffix;
  483.          else
  484.             Result := "";
  485.          end;
  486.       ensure
  487.          Result /= Void
  488.       end;
  489.  
  490.    object_suffix: STRING is
  491.          -- Of object File produced by the C Compiler.
  492.       once
  493.          if c_compiler = gcc then
  494.             Result := o_suffix;
  495.          elseif c_compiler = lcc_win32 then
  496.             Result := obj_suffix;
  497.          elseif c_compiler = cc then
  498.             if system_name = vms_system then
  499.                Result := obj_suffix;
  500.                Result.to_upper;
  501.             else
  502.                Result := o_suffix;
  503.             end;
  504.          elseif c_compiler = wcl386 then
  505.             Result := obj_suffix;
  506.          elseif c_compiler = bcc32 then
  507.             Result := obj_suffix;
  508.          elseif c_compiler = bcc32i then
  509.             Result := obj_suffix;
  510.          elseif c_compiler = cl then
  511.             Result := obj_suffix;
  512.          elseif c_compiler = sas_c then
  513.             Result := o_suffix;
  514.      elseif c_compiler = dice then
  515.         Result := o_suffix;
  516.      elseif c_compiler = vbcc then
  517.         Result := o_suffix;
  518.      elseif c_compiler = ccc then
  519.         Result := o_suffix;
  520.          end;
  521.       end;
  522.  
  523. feature {NATIVE_SMALL_EIFFEL}
  524.  
  525.    add_lib_math is
  526.       once
  527.          if beos_system = system_name then
  528.          elseif c_compiler = gcc then
  529.             append_token(external_lib,libm);
  530.          elseif c_compiler = bcc32 then
  531.             append_token(external_lib,libm);
  532.          elseif c_compiler = bcc32i then
  533.             append_token(external_lib,libm);
  534.          elseif c_compiler = cl then
  535.          elseif c_compiler = sas_c then
  536.         -- math library is included automatically if
  537.         -- "Math=..." was specified (as it is in
  538.         -- default `sas_c_compiler_options')
  539.      elseif c_compiler = dice then
  540.         append_token(external_lib,libm);
  541.      elseif c_compiler = vbcc then
  542.         if amiga_system = system_name then
  543.            append_token(external_lib,"-lmieee");
  544.         else
  545.            append_token(external_lib,libm);
  546.         end;
  547.      elseif c_compiler = ccc then
  548.         append_token(external_lib,libcpml);
  549.          end;
  550.       end;
  551.  
  552. feature {COMPILE,COMPILE_TO_C}
  553.  
  554.    extra_arg(arg: STRING; argi: INTEGER; next_arg: STRING): INTEGER is
  555.       require
  556.          arg /= Void;
  557.          argi >= 1
  558.       do
  559.          if arg.item(1) /= '-' then
  560.             if arg.has_suffix(object_suffix) then
  561.                append_token(external_object_files,arg);
  562.                Result := argi + 1;
  563.             elseif arg.has_suffix(c_suffix) then
  564.                append_token(external_c_files,arg);
  565.                Result := argi + 1;
  566.             elseif is_c_plus_plus_file_path(arg) then
  567.                append_token(external_c_plus_plus_files,arg);
  568.                Result := argi + 1;
  569.             elseif arg.has_suffix(".a") then
  570.                append_token(external_lib,arg);
  571.                Result := argi + 1;
  572.             elseif arg.has_suffix(".lib") then
  573.                append_token(external_lib,arg);
  574.                Result := argi + 1;
  575.             elseif arg.has_suffix(".res") then 
  576.                -- For lcc-win32 resource files :
  577.                append_token(external_lib,arg);
  578.                Result := argi + 1;
  579.             elseif run_control.root_class = Void then
  580.                run_control.compute_root_class(arg);
  581.                Result := argi + 1;
  582.                if next_arg /= Void then
  583.                   if next_arg.item(1) /= '-' then
  584.                      if next_arg.has_suffix(object_suffix) then
  585.                      elseif next_arg.has_suffix(c_suffix) then
  586.                      elseif is_c_plus_plus_file_path(next_arg) then
  587.                      else
  588.                         run_control.set_root_procedure(next_arg);
  589.                         Result := argi + 2;
  590.                      end;
  591.                   end;
  592.                end;
  593.             else
  594.                append_token(c_compiler_options,arg);
  595.                Result := argi + 1;
  596.             end;
  597.          elseif arg.has_prefix("-l") then
  598.             append_token(external_lib,arg);
  599.             Result := argi + 1;
  600.          elseif arg.has_prefix("-L") then
  601.             append_token(external_lib_path,arg);
  602.             if ("-L").is_equal(arg) then
  603.                if next_arg /= Void then
  604.                   append_token(external_lib_path,next_arg);
  605.                   Result := argi + 2;
  606.                end;
  607.             else
  608.                Result := argi + 1;
  609.             end;
  610.          elseif ("-subsystem").is_equal(arg) then
  611.             append_token(linker_options,arg);
  612.             if next_arg /= Void then
  613.                append_token(linker_options,next_arg);
  614.                Result := argi + 2;
  615.             else
  616.                Result := argi + 1;
  617.             end;
  618.          else
  619.             append_token(c_compiler_options,arg);
  620.             Result := argi + 1;
  621.          end;
  622.       ensure
  623.          Result > old argi
  624.       end;
  625.  
  626. feature {COMPILE,COMPILE_TO_C,CLEAN,INSTALL}
  627.  
  628.    set_c_compiler(cc_arg: STRING) is
  629.          -- If `cc_arg' is not Void, used `cc_arg' as the C compiler. Otherwise, 
  630.          -- read the selected one in the "SmallEiffel/sys/compiler.se" file.
  631.       local
  632.          i: INTEGER;
  633.          sd: STRING;
  634.          c: CHARACTER;
  635.       do
  636.          if cc_arg /= Void then
  637.             i := compiler_list.index_of(cc_arg);
  638.             if i > compiler_list.upper then
  639.                echo.w_put_string("compile_to_c: ");
  640.                echo.w_put_string(cc_arg);
  641.                echo.w_put_string(
  642.                " : unknown compiler name after -cc flag.%N");
  643.                show_compiler_list_then_exit;
  644.             end;
  645.             c_compiler := compiler_list.item(i);
  646.          else
  647.             sd := sys_directory;
  648.             tmp_path.copy(sd);
  649.             tmp_path.append("compiler.se");
  650.             echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  651.             c_compiler := echo.read_word_in(tmp_file_read);
  652.             i := compiler_list.index_of(c_compiler);
  653.             if i > compiler_list.upper then
  654.                echo.w_put_string("Unknown compiler name in file%N%"");
  655.                echo.w_put_string(tmp_file_read.path);
  656.                echo.w_put_string("%".%N");
  657.                show_compiler_list_then_exit;
  658.             end;
  659.             c_compiler := compiler_list.item(i);
  660.             if not tmp_file_read.end_of_input then
  661.                from
  662.                   c := tmp_file_read.last_character;
  663.                until
  664.                   c = '%N' or else c ='%R'
  665.                loop
  666.                   c_compiler_options.extend(c);
  667.                   tmp_file_read.read_character;
  668.                   if not tmp_file_read.end_of_input then
  669.                      c := tmp_file_read.last_character;
  670.                   end;
  671.                end;
  672.             end;
  673.             tmp_file_read.disconnect;
  674.             from
  675.             until c_compiler_options.is_empty or else
  676.                not c_compiler_options.first.is_separator
  677.             loop
  678.                c_compiler_options.remove_first(1);
  679.             end;
  680.             -- Setting default `c_compiler_options' only when there is no C 
  681.             -- compiler option after the name of the compiler we have just 
  682.             -- read in file "compiler.se". This allow the advanced user to 
  683.         -- tune exactly the C compiler according to its needs.
  684.             if c_compiler_options.is_empty then
  685.                if gcc = c_compiler then
  686.                   c_compiler_options.copy("-O2");
  687.                elseif lcc_win32 = c_compiler then
  688.                   c_compiler_options.copy("-O");
  689.                elseif cc = c_compiler then
  690.                   c_compiler_options.copy("-O");
  691.                elseif wcl386 = c_compiler then
  692.                elseif bcc32 = c_compiler then
  693.                   c_compiler_options.copy("-5 -w-aus -w-par -w-rvl -O2 -O-v");
  694.                elseif bcc32i = c_compiler then
  695.                   c_compiler_options.copy("-5 -w-aus -w-par -w-rvl -O2");
  696.                elseif cl = c_compiler then
  697.                   c_compiler_options.copy("-O2 -nologo -D%"WIN32%"");
  698.                elseif sas_c = c_compiler then
  699.           c_compiler_options.clear;
  700.           linker_options.copy("Link");
  701.           if not Scoptions_exists then
  702.              append_token(linker_options, "SmallCode SmallData");
  703.           end;
  704.            elseif dice = c_compiler then
  705.           c_compiler_options.copy("-mD -mC");
  706.            elseif vbcc = c_compiler then
  707.           if amiga_system = system_name then
  708.              c_compiler_options.copy("-DAMIGA");
  709.           end;
  710.            elseif ccc = c_compiler then
  711.           c_compiler_options.copy("-O2");
  712.                else
  713.                   check false end;
  714.                end;
  715.             end;
  716.          end;
  717.       ensure
  718.          compiler_list.fast_has(c_compiler)
  719.       end;
  720.    
  721. feature {COMPILE_TO_C}
  722.  
  723.    set_no_strip is
  724.       do
  725.          no_strip := true;
  726.       end;
  727.  
  728. feature {C_PRETTY_PRINTER}
  729.  
  730.    put_c_main_function_type(out_c: STD_FILE_WRITE) is
  731.       do
  732.          if vms_system = system_name then
  733.             out_c.put_string(fz_void);
  734.          else
  735.             out_c.put_string(fz_int);
  736.          end;
  737.       end;
  738.  
  739.    put_c_main_function_exit(out_c: STD_FILE_WRITE) is
  740.       do
  741.          out_c.put_string("}%Nexit(0);%N");
  742.          if vms_system = system_name then
  743.             out_c.put_string("return;}%N");
  744.          else
  745.             out_c.put_string("return 0;}%N");
  746.          end;
  747.       end;
  748.  
  749.    sys_runtime(name: STRING; suffix: CHARACTER) is
  750.          -- Prepare `tmp_file_read' to access the corresponding file
  751.          -- in the SmallEiffel/sys/runtime directory.
  752.       require
  753.          name /= Void;
  754.          suffix = 'c' or suffix = 'h'
  755.       do
  756.          tmp_path.copy(sys_directory);
  757.          add_directory(tmp_path,fz_runtime);
  758.          tmp_path.append(name);
  759.          tmp_path.extend('.');
  760.          tmp_path.extend(suffix);
  761.          echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  762.       ensure
  763.          tmp_file_read.is_connected
  764.       end;
  765.  
  766.    path_h: STRING is
  767.          -- Create a new STRING which is the name of the
  768.          -- main *.h file.
  769.       do
  770.          Result := run_control.root_class.twin;
  771.          Result.to_lower;
  772.          if dos_system = system_name then
  773.             from
  774.             until
  775.                Result.count <= 4
  776.             loop
  777.                Result.remove_last(1);
  778.             end;
  779.          end;
  780.          Result.append(h_suffix);
  781.       end;
  782.  
  783.    strip_executable(cmd: STRING): BOOLEAN is
  784.       local
  785.          output_name: STRING;
  786.       do
  787.          cmd.clear;
  788.          if not no_strip then
  789.             output_name := run_control.output_name;
  790.             if unix_system = system_name then
  791.                Result := true;
  792.                cmd.append("strip ");
  793.                if output_name = Void then
  794.                   cmd.append("a.out");
  795.                else
  796.                   cmd.append(output_name);
  797.                end;
  798.             elseif os2_system = system_name then
  799.                Result := true;
  800.                cmd.append("emxbind -qs ");
  801.                if output_name = Void then
  802.                   cmd.append("a.exe");
  803.                else
  804.                   cmd.append(output_name);
  805.                end;
  806.             end;
  807.          end;
  808.       end;
  809.  
  810.    add_c_plus_plus_file(f: STRING) is
  811.       require
  812.          is_c_plus_plus_file_path(f) 
  813.       do
  814.          append_token(external_c_plus_plus_files,f);
  815.      if c_compiler = gcc then
  816.         if gcc.item(2) = 'c' then
  817.            -- Switch "gcc" to "g++" :
  818.            c_compiler.put('+',2);
  819.            c_compiler.put('+',3);
  820.         end;
  821.      end;
  822.       end;
  823.  
  824. feature {C_PRETTY_PRINTER,INSTALL}
  825.  
  826.    split_mode_c_compiler_command(cmd, c_file_name: STRING) is
  827.          -- Where c_file_name is the name of one slice.
  828.       do
  829.          cmd.clear;
  830.          if c_compiler = gcc then
  831.             cmd.append(gcc);
  832.             append_token(cmd,c_compiler_options);
  833.             append_token(cmd,c_flag);
  834.             append_token(cmd,c_file_name);
  835.          elseif c_compiler = lcc_win32 then
  836.             cmd.append(lcc);
  837.             append_token(cmd,c_compiler_options);
  838.             append_token(cmd,c_file_name);
  839.          elseif c_compiler = cc then
  840.             cmd.append(cc);
  841.             append_token(cmd,c_compiler_options);
  842.             append_token(cmd,c_flag);
  843.             append_token(cmd,c_file_name);
  844.          elseif c_compiler = wcl386 then
  845.             cmd.append("wcc386");
  846.             append_token(cmd,c_compiler_options);
  847.             append_token(cmd,c_file_name);
  848.          elseif c_compiler = bcc32 then
  849.             cmd.append(bcc32);
  850.             append_token(cmd,c_compiler_options);
  851.             append_token(cmd,c_flag);
  852.             append_token(cmd,c_file_name);
  853.          elseif c_compiler = bcc32i then
  854.             cmd.append(bcc32i);
  855.             append_token(cmd,c_compiler_options);
  856.             append_token(cmd,c_flag);
  857.             append_token(cmd,c_file_name);
  858.          elseif c_compiler = cl then
  859.             cmd.append(cl);
  860.             append_token(cmd,c_compiler_options);
  861.             append_token(cmd,c_flag);
  862.             append_token(cmd,c_file_name);
  863.          elseif c_compiler = sas_c then
  864.             cmd.append(sas_c);
  865.         append_token(cmd,sas_c_compiler_options(true));
  866.         append_token(cmd,c_compiler_options);
  867.         append_token(cmd,c_file_name);
  868.      elseif c_compiler = dice then
  869.         cmd.append(dcc);
  870.         append_token(cmd,c_compiler_options);
  871.         append_token(cmd,c_flag);
  872.         append_token(cmd,c_file_name);
  873.      elseif c_compiler = vbcc then
  874.         cmd.append(vc);
  875.             append_token(cmd,c_compiler_options);
  876.         append_token(cmd,c_flag);
  877.             append_token(cmd,c_file_name);
  878.      elseif c_compiler = ccc then
  879.             cmd.append(ccc);
  880.             append_token(cmd,c_compiler_options);
  881.             append_token(cmd,c_flag);
  882.             append_token(cmd,c_file_name);
  883.          end;
  884.       end;
  885.  
  886.    split_mode_linker_command(cmd, c_name: STRING; max: INTEGER) is
  887.          -- Where `c_name' is only the prefix name (ie. "compile_to_c").
  888.       do
  889.          cmd.clear;
  890.          if c_compiler = gcc then
  891.             cmd.append(gcc);
  892.             append_token(cmd,c_compiler_options);
  893.             append_token(cmd,linker_options);
  894.             append_token(cmd,external_lib_path);
  895.             add_output_name(cmd);
  896.             add_objects(cmd,c_name,max);
  897.             append_token(cmd,external_c_files);
  898.             append_token(cmd,external_c_plus_plus_files);
  899.             append_token(cmd,external_object_files);
  900.             append_token(cmd,external_lib);
  901.          elseif c_compiler = lcc_win32 then
  902.             external_c_files_for_lcc_win32(cmd);
  903.             cmd.append(lcclnk);
  904.             if not no_strip then
  905.                append_token(cmd,s_flag);
  906.             end;
  907.             append_token(cmd,linker_options);
  908.             add_output_name(cmd);
  909.             add_objects(cmd,c_name,max);
  910.             append_token(cmd,external_object_files);
  911.             append_token(cmd,external_lib);
  912.          elseif c_compiler = cc then
  913.             cmd.append(cc);
  914.             append_token(cmd,c_compiler_options);
  915.             append_token(cmd,linker_options);
  916.             append_token(cmd,external_lib_path);
  917.             add_output_name(cmd);
  918.             add_objects(cmd,c_name,max);
  919.             append_token(cmd,external_c_files);
  920.             append_token(cmd,external_object_files);
  921.             append_token(cmd,external_lib);
  922.          elseif c_compiler = wcl386 then
  923.             cmd.append("wlink");
  924.             append_token(cmd,c_compiler_options);
  925.             append_token(cmd,linker_options);
  926.             append_token(cmd,external_lib_path);
  927.             add_output_name(cmd);
  928.             add_objects(cmd,c_name,max);
  929.             append_token(cmd,external_c_files);
  930.             append_token(cmd,external_object_files);
  931.             append_token(cmd,external_lib);
  932.          elseif c_compiler = bcc32 then
  933.             cmd.append(bcc32);
  934.             append_token(cmd,c_compiler_options);
  935.             append_token(cmd,linker_options);
  936.             append_token(cmd,external_lib_path);
  937.             add_output_name(cmd);
  938.             add_objects(cmd,c_name,max);
  939.             append_token(cmd,external_c_files);
  940.             append_token(cmd,external_object_files);
  941.             append_token(cmd,external_lib);
  942.             add_lib_math;
  943.          elseif c_compiler = bcc32i then
  944.             cmd.append(bcc32i);
  945.             append_token(cmd,c_compiler_options);
  946.             append_token(cmd,linker_options);
  947.             append_token(cmd,external_lib_path);
  948.             add_output_name(cmd);
  949.             add_objects(cmd,c_name,max);
  950.             append_token(cmd,external_c_files);
  951.             append_token(cmd,external_object_files);
  952.             append_token(cmd,external_lib);
  953.             add_lib_math;
  954.          elseif c_compiler = cl then
  955.             cmd.append(cl);
  956.             append_token(cmd,c_compiler_options);
  957.             append_token(cmd,linker_options);
  958.             append_token(cmd,external_lib_path);
  959.             add_output_name(cmd);
  960.             add_objects(cmd,c_name,max);
  961.             append_token(cmd,external_c_files);
  962.             append_token(cmd,external_object_files);
  963.             append_token(cmd,external_lib);
  964.             add_lib_math;
  965.          elseif c_compiler = sas_c then
  966.             cmd.append(sas_c);
  967.         append_token(cmd,sas_c_compiler_options(true));
  968.             append_token(cmd,c_compiler_options);
  969.             append_token(cmd,linker_options);
  970.             append_token(cmd,c_name);
  971.             cmd.append("#1#2#3#4#5#6#7#8#9#?.o");
  972.             append_token(cmd,external_c_files);
  973.             append_token(cmd,external_object_files);
  974.             append_token(cmd,external_lib);
  975.             add_output_name(cmd);
  976.             if not no_strip then
  977.                cmd.append(" StripDebug");
  978.             end;
  979.      elseif c_compiler = dice then
  980.         cmd.append(dcc);
  981.         append_token(cmd,c_compiler_options);
  982.         append_token(cmd,linker_options);
  983.         append_token(cmd,external_lib_path);
  984.         add_output_name(cmd);
  985.         add_objects(cmd,c_name,max);
  986.         append_token(cmd,external_c_files);
  987.         append_token(cmd,external_object_files);
  988.         append_token(cmd,external_lib);
  989.         if no_strip then
  990.            -- no typo; "-s" means "include symbol table",
  991.            -- not "strip debug information"
  992.            append_token(cmd,"-s -d1");
  993.         end;
  994.         add_lib_math;
  995.      elseif c_compiler = vbcc then
  996.         cmd.append(vc);
  997.         append_token(cmd,c_compiler_options);
  998.         append_token(cmd,linker_options);
  999.         append_token(cmd,external_lib_path);
  1000.         add_output_name(cmd);
  1001.         add_lib_math;
  1002.         add_objects(cmd,c_name,max);
  1003.         append_token(cmd,external_c_files);
  1004.         append_token(cmd,external_object_files);
  1005.         append_token(cmd,external_lib);
  1006.          elseif c_compiler = ccc then
  1007.             cmd.append(ccc);
  1008.             append_token(cmd,c_compiler_options);
  1009.             append_token(cmd,linker_options);
  1010.             append_token(cmd,external_lib_path);
  1011.             add_output_name(cmd);
  1012.             add_objects(cmd,c_name,max);
  1013.             append_token(cmd,external_c_files);
  1014.             append_token(cmd,external_c_plus_plus_files);
  1015.             append_token(cmd,external_object_files);
  1016.             append_token(cmd,external_lib);
  1017.          end;
  1018.       end;
  1019.  
  1020.    no_split_mode_command(cmd, c_file_name: STRING) is
  1021.       require
  1022.          c_file_name.has_suffix(".c")
  1023.       do
  1024.          cmd.clear;
  1025.          if c_compiler = gcc then
  1026.             cmd.append(gcc);
  1027.             append_token(cmd,c_compiler_options);
  1028.             append_token(cmd,linker_options);
  1029.             append_token(cmd,external_lib_path);
  1030.             add_output_name(cmd);
  1031.             append_token(cmd,c_file_name);
  1032.             append_token(cmd,external_c_files);
  1033.             append_token(cmd,external_c_plus_plus_files);
  1034.             append_token(cmd,external_object_files);
  1035.             append_token(cmd,external_lib);
  1036.          elseif c_compiler = lcc_win32 then
  1037.             cmd.append(lcc);
  1038.             append_token(cmd,c_compiler_options);
  1039.             append_token(cmd,c_file_name);
  1040.             cmd.extend('%N');
  1041.             external_c_files_for_lcc_win32(cmd);
  1042.             cmd.append(lcclnk);
  1043.             if not no_strip then
  1044.                append_token(cmd,s_flag);
  1045.             end;
  1046.             append_token(cmd,linker_options);
  1047.             add_output_name(cmd);
  1048.             c_file_name.remove_suffix(c_suffix);
  1049.             c_file_name.append(object_suffix);
  1050.             append_token(cmd,c_file_name);
  1051.             append_token(cmd,external_object_files);
  1052.             append_token(cmd,external_lib);
  1053.          elseif c_compiler = cc then
  1054.             cmd.append(cc);
  1055.             append_token(cmd,c_compiler_options);
  1056.             append_token(cmd,linker_options);
  1057.             append_token(cmd,external_lib_path);
  1058.             add_output_name(cmd);
  1059.             append_token(cmd,c_file_name);
  1060.             append_token(cmd,external_c_files);
  1061.             append_token(cmd,external_object_files);
  1062.             append_token(cmd,external_lib);
  1063.          elseif c_compiler = wcl386 then
  1064.             cmd.append(wcl386);
  1065.             append_token(cmd,c_compiler_options);
  1066.             append_token(cmd,linker_options);
  1067.             append_token(cmd,external_lib_path);
  1068.             add_output_name(cmd);
  1069.             append_token(cmd,c_file_name);
  1070.             append_token(cmd,external_c_files);
  1071.             append_token(cmd,external_object_files);
  1072.             append_token(cmd,external_lib);
  1073.          elseif c_compiler = bcc32 then
  1074.             cmd.append(bcc32);
  1075.             append_token(cmd,c_compiler_options);
  1076.             append_token(cmd,linker_options);
  1077.             append_token(cmd,external_lib_path);
  1078.             add_output_name(cmd);
  1079.             append_token(cmd,c_file_name);
  1080.             append_token(cmd,external_c_files);
  1081.             append_token(cmd,external_object_files);
  1082.             append_token(cmd,external_lib);
  1083.             add_lib_math;
  1084.          elseif c_compiler = bcc32i then
  1085.             cmd.append(bcc32i);
  1086.             append_token(cmd,c_compiler_options);
  1087.             append_token(cmd,linker_options);
  1088.             append_token(cmd,external_lib_path);
  1089.             add_output_name(cmd);
  1090.             append_token(cmd,c_file_name);
  1091.             append_token(cmd,external_c_files);
  1092.             append_token(cmd,external_object_files);
  1093.             append_token(cmd,external_lib);
  1094.             add_lib_math;
  1095.          elseif c_compiler = cl then
  1096.             cmd.append(cl);
  1097.             append_token(cmd,c_compiler_options);
  1098.             append_token(cmd,linker_options);
  1099.             append_token(cmd,external_lib_path);
  1100.             add_output_name(cmd);
  1101.             append_token(cmd,c_file_name);
  1102.             append_token(cmd,external_c_files);
  1103.             append_token(cmd,external_object_files);
  1104.             append_token(cmd,external_lib);
  1105.             add_lib_math;
  1106.          elseif c_compiler = sas_c then
  1107.             cmd.append(sas_c);
  1108.         append_token(cmd,sas_c_compiler_options(false));
  1109.             append_token(cmd,c_compiler_options);
  1110.         append_token(cmd,linker_options);
  1111.             append_token(cmd,external_lib_path);
  1112.             append_token(cmd,c_file_name);
  1113.             append_token(cmd,external_c_files);
  1114.             append_token(cmd,external_object_files);
  1115.             append_token(cmd,external_lib);
  1116.         add_lib_math;
  1117.             add_output_name(cmd);
  1118.      elseif c_compiler = dice then
  1119.         cmd.append(dcc);
  1120.         append_token(cmd,c_compiler_options);
  1121.         append_token(cmd,linker_options);
  1122.         append_token(cmd,external_lib_path);
  1123.         add_output_name(cmd);
  1124.         append_token(cmd,c_file_name);
  1125.         append_token(cmd,external_c_files);
  1126.         append_token(cmd,external_object_files);
  1127.         append_token(cmd,external_lib);
  1128.         add_lib_math;
  1129.         if no_strip then
  1130.            append_token(cmd,"-s");
  1131.         end;
  1132.      elseif c_compiler = vbcc then
  1133.         cmd.append(vc);
  1134.         append_token(cmd,c_compiler_options);
  1135.         append_token(cmd,linker_options);
  1136.         append_token(cmd,external_lib_path);
  1137.         add_output_name(cmd);
  1138.         add_lib_math;
  1139.         append_token(cmd,c_file_name);
  1140.         append_token(cmd,external_c_files);
  1141.         append_token(cmd,external_object_files);
  1142.         append_token(cmd,external_lib);
  1143.      elseif c_compiler = ccc then
  1144.         cmd.append(ccc);
  1145.         append_token(cmd,c_compiler_options);
  1146.         append_token(cmd,linker_options);
  1147.         append_token(cmd,external_lib_path);
  1148.         add_output_name(cmd);
  1149.         append_token(cmd,c_file_name);
  1150.         append_token(cmd,external_c_files);
  1151.         append_token(cmd,external_c_plus_plus_files);
  1152.         append_token(cmd,external_object_files);
  1153.         append_token(cmd,external_lib);
  1154.      end;
  1155.       end;
  1156.  
  1157. feature {NONE} -- SAS/c support functions:
  1158.  
  1159.    Scoptions_exists: BOOLEAN is
  1160.      -- Is there a file "SCOPTIONS" in the current directory?
  1161.       once
  1162.      Result := file_tools.is_readable("SCOPTIONS")
  1163.       end;
  1164.    
  1165.    sas_c_compiler_options(split: BOOLEAN): STRING is
  1166.      -- C compiler options or "" if no SCOPTIONS exists.
  1167.      -- If `split' is True, "Data=Far" is used, otherwise
  1168.      -- "Data=Auto".
  1169.       do
  1170.      if Scoptions_exists then
  1171.         Result := ""
  1172.      else
  1173.         !!Result.make(0)
  1174.         Result.append("Math=IEEE Parameters=Both Code=Far");
  1175.         -- cause bloat, but avoid linker errors
  1176.         if split then
  1177.            Result.append(" Data=Far");
  1178.         else
  1179.            Result.append(" Data=Auto");
  1180.         end
  1181.         Result.append(" Ignore=93,194,304");
  1182.         -- ignore the following warnings:
  1183.         --  93: no reference to identifier X
  1184.         -- 194: too much local data for NEAR reference,
  1185.         --      some changed to FAR (only with Data=Auto)
  1186.         -- 304: dead assignment eliminated
  1187.         Result.append(" NoVersion NoIcons");
  1188.         -- avoid cluttering the display with messages and
  1189.         -- the current directory with icon files
  1190.      end
  1191.       end;
  1192.    
  1193. feature {NONE}
  1194.  
  1195.    c_compiler: STRING;
  1196.          -- One item of `compiler_list'.
  1197.  
  1198.    c_compiler_options: STRING is "";
  1199.          -- C compiler options including extra include path,
  1200.          -- optimization flags, etc.
  1201.  
  1202.    external_object_files: STRING is "";
  1203.          -- External object files.
  1204.  
  1205.    external_c_files: STRING is "";
  1206.          -- External C files.
  1207.  
  1208.    external_lib_path: STRING is "";
  1209.          -- External libraries path to be added at link time.
  1210.  
  1211.    external_lib: STRING is "";
  1212.          -- External libraries to be added at link time.
  1213.  
  1214.    linker_options: STRING is "";
  1215.          -- Those options are only to be passed to the linker.
  1216.  
  1217.    external_c_plus_plus_files: STRING is "";
  1218.          -- External C++ files.
  1219.  
  1220.    append_token(head, tail: STRING) is
  1221.       do
  1222.          if not tail.is_empty then
  1223.             if tail.first /= ' ' then
  1224.                if not head.is_empty then
  1225.                   head.extend_unless(' ');
  1226.                end;
  1227.             end;
  1228.             head.append(tail);
  1229.          end;
  1230.       end;
  1231.    
  1232.    backslash_separator: BOOLEAN is
  1233.       do
  1234.          if windows_system = system_name then
  1235.             Result := true;
  1236.          elseif dos_system = system_name then
  1237.             Result := true;
  1238.          elseif os2_system = system_name then
  1239.             Result := true;
  1240.          end;
  1241.       end;
  1242.  
  1243.    loading_path_add(lp: ARRAY[STRING]; path: STRING; level: INTEGER) is
  1244.       local
  1245.          file: STD_FILE_READ;
  1246.          line: STRING;
  1247.       do
  1248.          if level > 5 or else lp.count > 1024 then
  1249.             echo.w_put_string(
  1250.                "Eiffel source loading path too long or infinite %
  1251.                %loadpath.se includes.%N");
  1252.             !!line.make(1024);
  1253.             append_lp_in(line,lp);
  1254.             echo.w_put_string(line);
  1255.             die_with_code(exit_failure_code);
  1256.          end;
  1257.          !!file.make;
  1258.          echo.sfr_connect(file,path);
  1259.          if file.is_connected then
  1260.             from
  1261.                echo.put_string("Append contents of  %"");
  1262.                echo.put_string(path);
  1263.                echo.put_string("%" to loading path.%N");
  1264.             until
  1265.                file.end_of_input
  1266.             loop
  1267.                file.read_line;
  1268.                line := file.last_string.twin;
  1269.                environment_variable_substitution(path,line);
  1270.                if line.has_suffix(fz_loadpath_se) then
  1271.                   loading_path_add(lp,line,level + 1);
  1272.                elseif line.is_empty then
  1273.                   if not file.end_of_input then
  1274.                      lp.add_last(line);
  1275.                   end;
  1276.                else
  1277.                   lp.add_last(line);
  1278.                end;
  1279.             end;
  1280.             file.disconnect;
  1281.          end;
  1282.       end;
  1283.  
  1284.    external_c_files_for_lcc_win32(cmd: STRING) is
  1285.          -- Because lcc_win32 does not accept *.c file while 
  1286.          -- linking as other C compiler do :-(
  1287.       local
  1288.          c_files: ARRAY[STRING];
  1289.          c_file: STRING;
  1290.          i: INTEGER;
  1291.       do
  1292.          if not external_c_files.is_empty then
  1293.             c_files := external_c_files.split;
  1294.             external_c_files.clear;
  1295.             if c_files /= Void then
  1296.                from
  1297.                   i := c_files.lower;
  1298.                until
  1299.                   i > c_files.upper
  1300.                loop
  1301.                   c_file := c_files.item(i);
  1302.                   cmd.append(lcc);
  1303.                   append_token(cmd,c_compiler_options);
  1304.                   append_token(cmd,c_file);
  1305.                   cmd.extend('%N');
  1306.                   c_file.remove_suffix(c_suffix);
  1307.                   c_file.append(object_suffix);
  1308.                   append_token(external_object_files,c_file);
  1309.                   i := i + 1;
  1310.                end;
  1311.             end;
  1312.          end;
  1313.       end;
  1314.  
  1315.    add_directory(path, dir: STRING) is
  1316.       require
  1317.          path.count > 0;
  1318.          dir.count > 0
  1319.       local
  1320.          last: CHARACTER;
  1321.       do
  1322.          if slash_separator then
  1323.             path.extend_unless('/');
  1324.             path.append(dir);
  1325.             path.extend_unless('/');
  1326.          elseif backslash_separator then
  1327.             path.extend_unless('\');
  1328.             path.append(dir);
  1329.             path.extend_unless('\');
  1330.          elseif macintosh_system = system_name then
  1331.             path.extend_unless(':');
  1332.             path.append(dir);
  1333.             path.extend_unless(':');
  1334.          elseif amiga_system = system_name then
  1335.             last := path.last;
  1336.             if last /= '/' and then last /= ':' then
  1337.                path.extend_unless('/');
  1338.             end;
  1339.             path.append(dir);
  1340.             path.extend_unless('/');
  1341.          elseif vms_system = system_name then
  1342.             path.extend_unless(']');
  1343.             path.remove_last(1);
  1344.             path.extend_unless('.');
  1345.             path.append(dir);
  1346.             path.extend_unless(']');
  1347.          else
  1348.             check
  1349.                false
  1350.             end;
  1351.          end;
  1352.       end;
  1353.  
  1354.    parent_directory(path: STRING) is
  1355.          -- Remove the last sub-directory of `path' (assume `path' is a
  1356.          -- combination of more than one directory).
  1357.       require
  1358.          path.count > 0
  1359.       do
  1360.          if slash_separator then
  1361.             from
  1362.                path.remove_last(1);
  1363.             until
  1364.                path.is_empty or else path.last = '/'
  1365.             loop
  1366.                path.remove_last(1);
  1367.             end;
  1368.          elseif backslash_separator then
  1369.             from
  1370.                path.remove_last(1);
  1371.             until
  1372.                path.is_empty or else path.last = '\'
  1373.             loop
  1374.                path.remove_last(1);
  1375.             end;
  1376.          elseif macintosh_system = system_name then
  1377.             from
  1378.                path.remove_last(1);
  1379.             until
  1380.                path.is_empty or else path.last = ':'
  1381.             loop
  1382.                path.remove_last(1);
  1383.             end;
  1384.          elseif amiga_system = system_name then
  1385.             from
  1386.                path.remove_last(1);
  1387.             until
  1388.                path.is_empty or else ("/:").has(path.last)
  1389.             loop
  1390.                path.remove_last(1);
  1391.             end;
  1392.          elseif vms_system = system_name then
  1393.             from
  1394.                path.remove_last(1);
  1395.             until
  1396.                path.is_empty or else path.last = '.'
  1397.             loop
  1398.                path.remove_last(1);
  1399.             end;
  1400.             path.remove_last(1);
  1401.             path.extend(']');
  1402.          else
  1403.             check
  1404.                false
  1405.             end;
  1406.          end;
  1407.       ensure
  1408.          path.count > 0;
  1409.          path.count < (old path.count)
  1410.       end;
  1411.  
  1412. feature {ID_PROVIDER}
  1413.  
  1414.    id_file_path: STRING is
  1415.       once
  1416.          Result := path_h;
  1417.          Result.remove_suffix(h_suffix);
  1418.          Result.append(".id");
  1419.       end;
  1420.  
  1421. feature {NONE}
  1422.  
  1423.    environment_variable_substitution(path, line: STRING) is
  1424.          -- If any, substitute some environment variable by it's value.
  1425.          -- The only one accepted notation is :
  1426.          --                                        ${...}
  1427.       local
  1428.          i, state, mem1, mem2: INTEGER;
  1429.          c: CHARACTER;
  1430.          value, variable: STRING;
  1431.       do
  1432.          from
  1433.             i := 1;
  1434.          until
  1435.             i > line.count
  1436.          loop
  1437.             c := line.item(i);
  1438.             inspect
  1439.                state
  1440.             when 0 then -- Initial state.
  1441.                if c = '$' then
  1442.                   state := 1;
  1443.                   mem1 := i;
  1444.                end;
  1445.             when 1 then -- "$" read.
  1446.                if c = '{' then
  1447.                   state := 2;
  1448.                   !!variable.make(8);
  1449.                else
  1450.                   state := 0;
  1451.                end;
  1452.             when 2 then -- "${" read.
  1453.                if c = '}' then
  1454.                   state := 3;
  1455.                   mem2 := i;
  1456.                else
  1457.                   variable.extend(c);
  1458.                end;
  1459.             else -- First correct variable found.
  1460.             end;
  1461.             i := i + 1;
  1462.          end;
  1463.          if state = 3 then
  1464.             value := get_environment_variable(variable);
  1465.             if value = Void then
  1466.                echo.w_put_string("Environment variable ${");
  1467.                echo.w_put_string(variable);
  1468.                echo.w_put_string("} of %"");
  1469.                echo.w_put_string(path);
  1470.                echo.w_put_string("%" is not set.%N");
  1471.             else
  1472.                variable.copy(line);
  1473.                line.head(mem1 - 1);
  1474.                line.append(value);
  1475.                variable.remove_first(mem2);
  1476.                line.append(variable);
  1477.                environment_variable_substitution(path,line)
  1478.             end;
  1479.          end;
  1480.       end;
  1481.  
  1482.    slash_separator: BOOLEAN is
  1483.       do
  1484.          if unix_system = system_name then
  1485.             Result := true;
  1486.          elseif beos_system = system_name then
  1487.             Result := true;
  1488.          end;
  1489.       end;
  1490.  
  1491.    show_compiler_list_then_exit is
  1492.       local
  1493.          i: INTEGER;
  1494.       do
  1495.          echo.w_put_string("Currently handled compiler names:%N");
  1496.          from
  1497.             i := 1;
  1498.          until
  1499.             i > compiler_list.upper
  1500.          loop
  1501.             echo.w_put_string(compiler_list.item(i));
  1502.             echo.w_put_character('%N');
  1503.             i := i + 1;
  1504.          end;
  1505.          die_with_code(exit_failure_code);
  1506.       end;
  1507.  
  1508.    add_output_name(cmd: STRING) is
  1509.       local
  1510.          output_name: STRING;
  1511.       do
  1512.          output_name := run_control.output_name;
  1513.          if output_name = Void then
  1514.             output_name := run_control.root_class.twin;
  1515.             output_name.to_lower;
  1516.             if c_compiler = lcc_win32 then
  1517.                append_token(cmd,o_flag);
  1518.                append_token(cmd,output_name);
  1519.                add_x_suffix(cmd);
  1520.             elseif c_compiler = bcc32 then
  1521.                append_token(cmd,e_flag);
  1522.                cmd.append(output_name);
  1523.                add_x_suffix(cmd);
  1524.             elseif c_compiler = bcc32i then
  1525.                append_token(cmd,e_flag);
  1526.                cmd.append(output_name);
  1527.                add_x_suffix(cmd);
  1528.             elseif c_compiler = wcl386 then
  1529.                append_token(cmd,o_flag);
  1530.                cmd.append(output_name);
  1531.                add_x_suffix(cmd);
  1532.             elseif c_compiler = sas_c then
  1533.                output_name := run_control.root_class.twin;
  1534.                output_name.to_lower;
  1535.                cmd.append(fz_to_);
  1536.                cmd.append(output_name);
  1537.         elseif c_compiler = dice then
  1538.            append_token(cmd,o_flag);
  1539.            cmd.append(output_name);
  1540.         elseif c_compiler = vbcc then
  1541.            append_token(cmd,o_flag);
  1542.            cmd.append(output_name);
  1543.             end;
  1544.          elseif c_compiler = gcc then
  1545.             append_token(cmd,o_flag);
  1546.             append_token(cmd,output_name);
  1547.             add_x_suffix(cmd);
  1548.          elseif c_compiler = lcc_win32 then
  1549.             append_token(cmd,o_flag);
  1550.             append_token(cmd,output_name);
  1551.             add_x_suffix(cmd);
  1552.          elseif c_compiler = cc then
  1553.             append_token(cmd,o_flag);
  1554.             append_token(cmd,output_name);
  1555.             add_x_suffix(cmd);
  1556.          elseif c_compiler = wcl386 then
  1557.             append_token(cmd,o_flag);
  1558.             append_token(cmd,output_name);
  1559.             add_x_suffix(cmd);
  1560.          elseif c_compiler = bcc32 then
  1561.             append_token(cmd,e_flag);
  1562.             cmd.append(output_name);
  1563.             add_x_suffix(cmd);
  1564.          elseif c_compiler = bcc32i then
  1565.             append_token(cmd,e_flag);
  1566.             cmd.append(output_name);
  1567.             add_x_suffix(cmd);
  1568.          elseif c_compiler = cl then
  1569.             append_token(cmd,o_flag);
  1570.             cmd.append(output_name);
  1571.             add_x_suffix(cmd);
  1572.          elseif c_compiler = sas_c then
  1573.             cmd.append(fz_to_);
  1574.             append_token(cmd,output_name);
  1575.      elseif c_compiler = dice then
  1576.         append_token(cmd,o_flag);
  1577.         append_token(cmd,output_name);
  1578.         add_x_suffix(cmd);
  1579.      elseif c_compiler = vbcc then
  1580.         append_token(cmd,o_flag);
  1581.         append_token(cmd,output_name);
  1582.         add_x_suffix(cmd);
  1583.          elseif c_compiler = ccc then
  1584.             append_token(cmd,o_flag);
  1585.             append_token(cmd,output_name);
  1586.             add_x_suffix(cmd);
  1587.          end;
  1588.       end;
  1589.  
  1590.    no_strip: BOOLEAN;
  1591.  
  1592.    add_objects(cmd, c_name: STRING; max: INTEGER) is
  1593.       local
  1594.          i: INTEGER;
  1595.       do
  1596.          from
  1597.             i := 1;
  1598.          until
  1599.             i > max
  1600.          loop
  1601.             append_token(cmd,c_name);
  1602.             i.append_in(cmd);
  1603.             cmd.append(object_suffix);
  1604.             i := i + 1;
  1605.          end;
  1606.       end;
  1607.  
  1608.    exe_suffix: STRING is ".exe";
  1609.  
  1610.    o_suffix: STRING is ".o";
  1611.  
  1612.    obj_suffix: STRING is ".obj";
  1613.  
  1614.    c_flag: STRING is "-c";
  1615.  
  1616.    o_flag: STRING is "-o";
  1617.  
  1618.    e_flag: STRING is "-e";
  1619.  
  1620.    s_flag: STRING is "-s";
  1621.  
  1622.    lcc: STRING is "lcc";
  1623.  
  1624.    vc: STRING is "vc";
  1625.  
  1626.    dcc: STRING is "dcc";
  1627.  
  1628.    lcclnk: STRING is "lcclnk";
  1629.  
  1630.    lnk_suffix: STRING is ".lnk";
  1631.  
  1632.    libm: STRING is "-lm";
  1633.  
  1634.    libcpml: STRING is "-lcpml";
  1635.  
  1636.    fz_to_: STRING is " To ";
  1637.  
  1638.    fz_loadpath_se: STRING is "loadpath.se";
  1639.  
  1640.    singleton_memory: SYSTEM_TOOLS is
  1641.       once
  1642.          Result := Current;
  1643.       end;
  1644.  
  1645. invariant
  1646.  
  1647.    is_real_singleton: Current = singleton_memory
  1648.  
  1649. end -- SYSTEM_TOOLS
  1650.